package main

import (
	"fmt"
	"math"
	"os"
	"bufio"
	"strconv"
)

const (
	width, height = 600, 320
	cells = 100
	xyrange = 30.0
	xyscale = width / 2 / xyrange
	zscale = height * 0.4
	angle = math.Pi / 6
)

var sin30, cos30 = math.Sin(angle), math.Cos(angle)

func main() {
	filePath := "C:/Users/lihq1/Desktop/test/go/surface.svg"
	file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_CREATE, 0666)
	if err != nil {
		fmt.Printf("open file error=%v\n", err)
		return
	}
	defer file.Close()
	s := svg()

	fmt.Printf("svg", svg())
	writer := bufio.NewWriter(file)
	
	writer.WriteString(s)
	
	writer.Flush()
}

func svg() string {
	str := "<svg xmlns='http://www.w3.org/2000/svg' style='stroke: grey; fill: white; stroke-width:0.7' width='600' height='320' >"

	// fmt.Printf("<svg xmlns='http://www.w3.org/2000/svg' " + "style='stroke: grey; fill: white; stroke-width:0.7' "+ "width='%d' height='%d'>",width,height)

	for i := 0; i < cells; i++ {
		for j := 0; j < cells; j++ {
			ax, ay := corner(i+1, j)
			bx, by := corner(i, j)
			cx, cy := corner(i, j+1)
			dx, dy := corner(i+1, j+1)
			// fmt.Printf(
			// 	"<polygon points='%g,%g %g,%g %g,%g %g,%g'/>\n",
			// 	ax, ay, bx, by, cx, cy, dx, dy)
			str += "<polygon points='" + strconv.FormatFloat(ax,'f', 6, 64) + "," + strconv.FormatFloat(ay,'f', 6,  64) + " " + strconv.FormatFloat(bx,'f', 6,  64) + "," + strconv.FormatFloat(by,'f', 6,  64) + " " + strconv.FormatFloat(cx,'f', 6,  64) + "," + strconv.FormatFloat(cy,'f', 6,  64) + " " + strconv.FormatFloat(dx,'f', 6,  64) + "," + strconv.FormatFloat(dy,'f', 6,  64) + " " + "'/>\n"
		}
	}

	str += "</svg>"

	return str;
}

func corner(i, j int) (float64, float64) {
	x := xyrange * (float64(i)/cells - 0.5)
	y := xyrange * (float64(j)/cells - 0.5)

	z := f(x, y)

	sx := width/2 + (x-y)*cos30*xyscale
	sy := height/2 + (x+y)*sin30*xyscale - z*zscale

	return sx, sy
}

func f(x, y float64) float64 {
	r := math.Hypot(x, y)
	return math.Sin(r) / r;
}